﻿using System;
using NHibernate;

namespace Xenta
{
    /// <summary>
    /// Exposes the unit of work factory interface.
    /// </summary>
    /// <remarks>
    /// This factory allows to abstract from concrete 
    /// implmentaion of the IUnitOfWork interface.
    /// </remarks>
    public interface IUnitOfWorkFactory : IDisposable
    {
        /// <summary>
        /// Creates an instance of the implementation of IUnitOfWork interface.
        /// </summary>
        /// <returns>The implementation instance.</returns>
        IUnitOfWork Produce();
    }

    /// <summary>
    /// The IUnitOfWorkFactory implementation.
    /// </summary>
    public class UnitOfWorkFactoryImpl : IUnitOfWorkFactory
    {
        #region Fields

        private readonly ISessionFactory _factory;

        #endregion

        #region Ctors

        /// <summary>
        /// Initializes a new instance of the class.
        /// </summary>
        /// <param name="factory">The session factory.</param>
        public UnitOfWorkFactoryImpl(ISessionFactory factory)
        {
            if(factory == null)
                throw new ArgumentNullException("factory");
            _factory = factory;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Creates an instance of the implementation of IUnitOfWork interface.
        /// </summary>
        /// <returns>The implementation instance.</returns>
        public IUnitOfWork Produce()
        {
            return new UnitOfWorkImpl(_factory);
        }

        /// <summary>
        /// Disposes the associated session factory.
        /// </summary>
        public void Dispose()
        {
            _factory.Dispose();
        }

        #endregion
    }
}
